<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>

  <div id="root">
    <p>{{name}}</p>
    <p>{{message}}</p>
  </div>

  <script>
    /*
    vue与模板
    1.编写页面模板
    2.使用vue的实例
      1.data,methods,computed,watch
    3.将vue和模板结合，渲染页面


    数据驱动：
    1.vue获取模板，有坑
    2.利用vue构造函数中的数据，填坑，可以在页面中显示的“标签”
    3.将标签替换页面中原来有坑的标签。--- 替换坑，在vue实例的前后打印出root，查看高亮

    let app = new Vue({
      el: '#root',
      data:{
        name: '张三',
        message: '一条消息'
      }
    })


    vue利用我们提供 数据和页面中的模板生成了一个新的html标签或者node节点，替换到了页面中放置模板的位置，

    我们怎么实现？？？


    */
    
    /*
    1. 获取模板
    2.获取数据
    3.将数据和模板结合，得到的是html元素（dom元素）
    4.替换到页面中
    */

    // 正则表达式
    let rkuohao = /\{\{(.+?)\}\}/g;
    // 1.获取模板
    let tmpNode = document.querySelector('#root')
    // 2.获取数据
    let data = {
      name: '张三',
      message: '这是一条消息'
    }
    // 3.将数据和模板结合（正则，递归）。template是dom元素，真正vue源码中是字符串--》vNode，
    function compiler(template, data) {
      let childNode = template.childNodes; // 获取子元素
      for(let i =0;i<childNode.length; i++) {
        // 判断是文本还是元素，文本可能有{{}}
        let type = childNode[i].nodeType; // 1.元素，3.文本
        
        if(type ===3) {
          // 文本节点，判断有没有{{}}
          let txt = childNode[i].nodeValue; // 该属性只有文本节点才有意义，文本节点值
          // 判断文本有没有{{}},用正则表达式rkuohao匹配txt文本，匹配到之后会执行function回调，回调的参数，第一个为匹配到的正则，第二个为替换的值
          txt = txt.replace(rkuohao, function(_, g) {
            // replace使用正则匹配一次就会被调用一次，函数参数0，表示匹配到的内容，第n个参数表示第n组
            let key = g.trim(); // {{}}里边的值，为key，在这里是name和message
            let value = data[key];
            // 将{{}}用value值替换
            return value;
          })
          
          // 注意txt现在和dom元素是没有关系的
          childNode[i].nodeValue = txt;

        } else if(type === 1) {
          // 元素，有没有子元素，判断子元素有没有{{}}，递归
          compiler(childNode[i], data)
        }

      }
    }

    let generateNode = tmpNode.cloneNode(true);// 注意这里是dom元素，可以这么用
    console.log(tmpNode)
    compiler(generateNode, data);
    console.log(generateNode)
    // 我们此时是没有生成新的template，所以这里看到的是直接在页面中就更新的数据，dom是引用类型
    // 这样做模板就没有了，下次更新的话就没有坑了

    // 4.放置到页面中
    root.parentNode.replaceChild(generateNode, root)

    /*
    问题：
    1.vue使用的虚拟dom，目前是真实dom。
    2.只考虑到了单属性，{{name}}，而vue中大量的使用层级{{userinfo.name.firstname}}
    3.代码没有整合
    */
  </script>
</body>
</html>